import { loadImage, getFixedImageSize } from './image-helper'
import { add, minus, multiply, divide } from 'util'
import '../stylus/index.styl'

let record = []
let frames = []
let scale = 1
let offset = {x: 0, y: 0}
let isMarking = false

function toggleSelection () {
    let btn = document.querySelectorAll('header .icon')[0]
    let canvas = document.querySelectorAll('canvas')
    btn.addEventListener('click', () => {
        let classes = btn.classList
        isMarking = !isMarking
        isMarking ? classes.add('active') : classes.remove('active')
        canvas.forEach(item => (isMarking ? item.classList.add('marking') : item.classList.remove('marking')))
    })
}

function registerZoomEvent (elements) {
    elements.forEach(item => {
        let el = item.el
        let left = el.offsetLeft
        let top = el.offsetTop
        let MAX_SCALE = 5
        let prevPoint = {x: -1, y: -1}
        el.addEventListener('mousewheel', e => {
            let isZoomIn = e.deltaY < 0
            let mouse = {x: e.pageX, y: e.pageY}
            let prevScale = scale

            if (isZoomIn) {
                scale += (scale < MAX_SCALE ? 0.1 : 0)
            } else {
                scale -= (scale > 1 ? 0.1 : 0)
            }
            offset.x = (left - mouse.x) * (scale - prevScale) / prevScale + offset.x / prevScale * scale
            offset.y = (top - mouse.y) * (scale - prevScale) / prevScale + offset.y / prevScale * scale
            elements.forEach(v => {
                let ctx = v.el.getContext('2d')
                let size = {x: v.el.width, y: v.el.height}
                ctx.clearRect(0, 0, size.x, size.y)
                ctx.drawImage(v.image, offset.x, offset.y, size.x * scale, size.y * scale)
                console.log(frames, '----------')
                frames.forEach(frame => {
                    let {x, y, width, height} = frame
                    ctx.strokeRect(x * size.x * scale + offset.x, y * size.y * scale + offset.y, width * size.x * scale, height * size.y * scale)
                })
            })
        })
    })
}

function drawSelection (elements, rect) {
    elements.forEach(item => {
        let el = item.el
        let ctx = el.getContext('2d')
        let size = {x: el.width, y: el.height}
        ctx.clearRect(0, 0, size.x, size.y)
        ctx.drawImage(item.image, offset.x, offset.y, size.x * scale, size.y * scale)
        ctx.strokeStyle = 'red'
        ctx.lineWidth = 1
        ctx.strokeRect(rect.x, rect.y, rect.width, rect.height)
        frames.forEach(frame => {
            let {x, y, width, height} = frame
            ctx.strokeRect(x * scale * size.x + offset.x, y * scale * size.y + offset.y, width * size.x * scale, height * size.y * scale)
        })
    })
}

function isPointInsideImage (point, imageSize, el) {
    let [left, top] = [el.offsetLeft, el.offsetTop]
    let [x, y] = [point.x - left, point.y - top]
    let [ws, hs] = [el.width * scale, el.height * scale]
    return !(x > ws + offset.x || y > hs + offset.y || x < offset.x || y < offset.y)
}

function getMarkPointOutsideImage (currentPoint, el) {
    let [left, top] = [el.offsetLeft, el.offsetTop]
    let [x, y] = [currentPoint.x - left, currentPoint.y - top]
    let [ws, hs] = [el.width * scale, el.height * scale]
    return {
        x: (x < offset.x ? offset.x : (x > ws + offset.x ? ws + offset.x : x)) + left,
        y: (y < offset.y ? offset.y : (y > hs + offset.y ? hs + offset.y : y)) + top
    }
}

function dragHandler (elements, start, current) {
    let [dx, dy] = [current.x - start.x, current.y - start.y]
    elements.forEach(item => {
        let el = item.el
        let ctx = el.getContext('2d')
        let size = {x: el.width, y: el.height}
        ctx.clearRect(0, 0, size.x, size.y)
        ctx.drawImage(item.image, offset.x + dx, offset.y + dy, size.x * scale, size.y * scale)
        ctx.strokeStyle = 'red'
        ctx.lineWidth = 1
        frames.forEach(frame => {
            let {x, y, width, height} = frame
            ctx.strokeRect(x * scale * size.x + offset.x + dx, y * scale * size.y + offset.y + dy, width * size.x * scale, height * size.y * scale)
        })
    })
}

function registerDragEvent (elements) {
    elements.forEach(item => {
        let el = item.el
        let isMouseDown = false
        let left = el.offsetLeft
        let top = el.offsetTop
        let size = {x: el.width, y: el.height}
        let rect = {x: 0, y: 0, width: 0, height: 0}
        let start = {x: 0, y: 0}
        let isStop = false
        let isDraging = false

        el.addEventListener('mousedown', e => {
            isMouseDown = true
            isStop = false
            start = {x: e.pageX, y: e.pageY}
            rect = {x: 0, y: 0, width: 0, height: 0}
        })
        window.addEventListener('mousemove', e => {
            let current = {x: e.pageX, y: e.pageY}
            if (!isMouseDown) {
                return
            }
            if (!isPointInsideImage(start, size, el)) {
                return
            }
            if (isMarking) {
                if (!isStop) {
                    if (!isPointInsideImage(current, size, el)) {
                        current = getMarkPointOutsideImage(current, el)
                    }
                    rect = {
                        x: start.x - left,
                        y: start.y - top,
                        width: current.x - start.x,
                        height: current.y - start.y
                    }
                    drawSelection(elements, rect)
                }
            } else {
                dragHandler(elements, start, current)
                isDraging = true
            }
        })
        el.addEventListener('mouseup', e => {
            isStop = true
            isMouseDown = false
            if (isDraging) {
                offset.x += e.pageX - start.x
                offset.y += e.pageY - start.y
                isDraging = false
                return
            }
            if (rect.width === 0 || rect.height === 0 || !isMarking) {
                return
            }
            frames.push({
                x: (rect.x - offset.x) / (el.width * scale),
                y: (rect.y - offset.y) / (el.height * scale),
                width: rect.width / (el.width * scale),
                height: rect.height / (el.height * scale)
            })
        })
        el.addEventListener('mouseleave', e => {
            if (isDraging) {
                isMouseDown = false
                offset.x += e.pageX - start.x
                offset.y += e.pageY - start.y
                isDraging = false
            }
        })
    })
}

function init (elements) {
    elements.forEach(item => {
        let el = item.el
        let ctx = el.getContext('2d')
        ctx.clearRect(0, 0, el.width, el.height)
        ctx.drawImage(item.image, offset.x, offset.y, el.width * scale, el.height * scale)
        ctx.strokeStyle = 'red'
        ctx.lineWidth = 1
        frames.forEach(frame => {
            let {x, y, width, height} = frame
            ctx.strokeRect(x * scale * el.width + offset.x, y * scale * el.height + offset.y, width * el.width * scale, height * el.height * scale)
        })
    })
}

window.onload = () => {
    let origin = document.querySelector('#origin')
    let filtered = document.querySelector('#filtered')
    let originCtx = origin.getContext('2d')
    let filteredCtx = filtered.getContext('2d')
    let imageUrlOrigin = '/assets/1.jpg'
    let imageUrlAfter = '/assets/2.jpg'

    Promise.all([
        loadImage(imageUrlOrigin),
        loadImage(imageUrlAfter)
    ]).then(images => {
        let size = getFixedImageSize(images[0], 600, 400)

        origin.width = size.width
        origin.height = size.height
        filtered.width = size.width
        filtered.height = size.height
        init([{el: origin, image: images[0]}, {el: filtered, image: images[1]}])

        registerZoomEvent([{el: origin, image: images[0]}, {el: filtered, image: images[1]}])
        registerDragEvent([{el: origin, image: images[0]}, {el: filtered, image: images[1]}])
        toggleSelection()
    })
}
